package com.coldlz.mmp.proxy.handlerclient;

import com.coldlz.mmp.proxy.Interceptor;
import com.coldlz.mmp.proxy.ProxyInfo;
import com.coldlz.mmp.proxy.UserContext;
import com.coldlz.mmp.proxy.WebSocketHandshakeRequest;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.SocketAddress;
import java.net.URI;
import java.util.List;
import java.util.Map;

public class ClientProxyWsHandler extends ChannelDuplexHandler {
    private static final Logger log = LoggerFactory.getLogger(ClientProxyWsHandler.class);
    private final UserContext userContext;
    private final Channel clientChannel;

    public ClientProxyWsHandler(UserContext userContext) {
        this.userContext = userContext;
        this.clientChannel = userContext.getClientChannel();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        userContext.setRemoteChannel(ctx.channel());
        userContext.getProxyInfo().setRemoteAddress(ctx.channel().remoteAddress().toString());
        super.channelActive(ctx);
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object obj) {
        log.info("收到ws响应" + obj.getClass());
        if (obj instanceof WebSocketFrame webSocketFrame) {
            clientChannel.writeAndFlush(webSocketFrame).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess() && future.cause() != null) {
                    log.error("发送 WebSocketFrame 数据异常.. ", future.cause());
                }
            });
        } else if (obj instanceof HttpObject httpObject) {
            clientChannel./*pipeline().context(HttpServerCodec.class).*/writeAndFlush(httpObject).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess() && future.cause() != null) {
                    log.error("发送 HttpObject 数据异常.. ", future.cause());
                }
            });
        } else if (obj instanceof ByteBuf byteBuf) {
            clientChannel.pipeline().firstContext().writeAndFlush(byteBuf).addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess() && future.cause() != null) {
                    log.error("发送 ByteBuf 数据异常.. ", future.cause());
                }
            });
        } else {
            throw new RuntimeException("未知类型");
        }
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        super.write(ctx, msg, promise);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("发生异常信息{}", ctx.name(), cause);
        userContext.close();// 通道发生异常 关闭
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
    }

}